package pers.cyril.jdb.server.netty.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import pers.cyril.jdb.protocol.packet.CreateDatabaseRequestPacket;
import pers.cyril.jdb.protocol.packet.CreateDatabaseResponsePacket;
import pers.cyril.jdb.server.cache.DatabaseCacheManager;
import pers.cyril.jdb.server.config.ServerConfig;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 说点什么吧
 *
 * @author Wang Cyril
 * @date 2024/6/1 16:34
 */
@ChannelHandler.Sharable
@Slf4j
public class CreateDatabaseRequestHandler extends SimpleChannelInboundHandler<CreateDatabaseRequestPacket> {

    public static final CreateDatabaseRequestHandler INSTANCE = new CreateDatabaseRequestHandler();

    private CreateDatabaseRequestHandler() {

    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, CreateDatabaseRequestPacket msg) throws Exception {
        if (!checkDatabaseExists(msg)) {
            //create database
            createDatabase(ctx, msg);
        } else {
            CreateDatabaseResponsePacket response = new CreateDatabaseResponsePacket();
            response.setSuccess(false);
            response.setMessage(String.format("database %s already exists", msg.getDatabase()));
            ctx.writeAndFlush(response);
        }

    }

    private void createDatabase(ChannelHandlerContext ctx, CreateDatabaseRequestPacket msg) throws IOException {
        BufferedWriter bufferedWriter = null;
        try {
            //create database dir
            Files.createDirectory(Paths.get(ServerConfig.INSTANCE.getDataDir(), msg.getDatabase()));
            Path filePath = Paths.get(ServerConfig.INSTANCE.getDataDir(), msg.getDatabase(), String.format("%s.db", msg.getDatabase()));
            Files.createFile(filePath);
            bufferedWriter = new BufferedWriter(new FileWriter(filePath.toFile()));
            bufferedWriter.write(msg.getDatabase());
            bufferedWriter.newLine();
            DatabaseCacheManager.INSTANCE.addDatabase(msg.getDatabase());
            CreateDatabaseResponsePacket packet = new CreateDatabaseResponsePacket();
            packet.setSuccess(true);
            ctx.writeAndFlush(packet);
        } catch (Exception e) {
            log.error("create database {} error", msg.getDatabase(), e);
            DatabaseCacheManager.INSTANCE.removeDatabase(msg.getDatabase());
            Files.delete(Paths.get(ServerConfig.INSTANCE.getDataDir(), msg.getDatabase()));
            CreateDatabaseResponsePacket packet = new CreateDatabaseResponsePacket();
            packet.setSuccess(false);
            packet.setMessage(e.getMessage());
            ctx.writeAndFlush(packet);
        } finally {
            if(bufferedWriter != null){
                bufferedWriter.close();
            }
        }

    }

    private boolean checkDatabaseExists(CreateDatabaseRequestPacket msg) {
        return Files.exists(Paths.get(ServerConfig.INSTANCE.getDataDir(), msg.getDatabase()));
    }
}
